home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / hity wydania / Ubuntu 9.10 PL / karmelkowy-koliberek-desktop-9.10-i386-PL.iso / casper / filesystem.squashfs / usr / share / hplip / base / utils.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2009-10-28  |  49.1 KB  |  1,695 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. from __future__ import generators
  5. import sys
  6. import os
  7. import fnmatch
  8. import tempfile
  9. import socket
  10. import struct
  11. import select
  12. import time
  13. import fcntl
  14. import errno
  15. import stat
  16. import string
  17. import commands
  18. import cStringIO
  19. import re
  20. import xml.parsers.expat as expat
  21. import getpass
  22. import locale
  23. import htmlentitydefs
  24.  
  25. try:
  26.     import platform
  27.     platform_avail = True
  28. except ImportError:
  29.     platform_avail = False
  30.  
  31. from g import *
  32. from codes import *
  33. import pexpect
  34. BIG_ENDIAN = 0
  35. LITTLE_ENDIAN = 1
  36.  
  37. def lock(f):
  38.     log.debug('Locking: %s' % f.name)
  39.     
  40.     try:
  41.         fcntl.flock(f.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB)
  42.         return True
  43.     except (IOError, OSError):
  44.         log.debug('Failed to unlock %s.' % f.name)
  45.         return False
  46.  
  47.  
  48.  
  49. def unlock(f):
  50.     if f is not None:
  51.         log.debug('Unlocking: %s' % f.name)
  52.         
  53.         try:
  54.             fcntl.flock(f.fileno(), fcntl.LOCK_UN)
  55.             os.remove(f.name)
  56.         except (IOError, OSError):
  57.             pass
  58.         except:
  59.             None<EXCEPTION MATCH>(IOError, OSError)
  60.         
  61.  
  62.     None<EXCEPTION MATCH>(IOError, OSError)
  63.  
  64.  
  65. def lock_app(application, suppress_error = False):
  66.     dir = prop.user_dir
  67.     if os.geteuid() == 0:
  68.         dir = '/var'
  69.     elif not os.path.exists(dir):
  70.         os.makedirs(dir)
  71.     
  72.     lock_file = os.path.join(dir, '.'.join([
  73.         application,
  74.         'lock']))
  75.     
  76.     try:
  77.         lock_file_f = open(lock_file, 'w')
  78.     except IOError:
  79.         if not suppress_error:
  80.             log.error('Unable to open %s lock file.' % lock_file)
  81.         
  82.         return (False, None)
  83.  
  84.     if not lock(lock_file_f):
  85.         if not suppress_error:
  86.             log.error('Unable to lock %s. Is %s already running?' % (lock_file, application))
  87.         
  88.         return (False, None)
  89.     return (True, lock_file_f)
  90.  
  91.  
  92. def Translator(frm = '', to = '', delete = '', keep = None):
  93.     allchars = string.maketrans('', '')
  94.     if len(to) == 1:
  95.         to = to * len(frm)
  96.     
  97.     trans = string.maketrans(frm, to)
  98.     if keep is not None:
  99.         delete = allchars.translate(allchars, keep.translate(allchars, delete))
  100.     
  101.     
  102.     def callable(s):
  103.         return s.translate(trans, delete)
  104.  
  105.     return callable
  106.  
  107.  
  108. def to_bool_str(s, default = '0'):
  109.     ''' Convert an arbitrary 0/1/T/F/Y/N string to a normalized string 0/1.'''
  110.     return default
  111.  
  112.  
  113. def to_bool(s, default = False):
  114.     ''' Convert an arbitrary 0/1/T/F/Y/N string to a boolean True/False value.'''
  115.     if isinstance(s, str) and s:
  116.         if s[0].lower() in ('1', 't', 'y'):
  117.             return True
  118.         if s[0].lower() in ('0', 'f', 'n'):
  119.             return False
  120.     elif isinstance(s, bool):
  121.         return s
  122.     s[0].lower() in ('1', 't', 'y')
  123.     return default
  124.  
  125.  
  126. def walkFiles(root, recurse = True, abs_paths = False, return_folders = False, pattern = '*', path = None):
  127.     if path is None:
  128.         path = root
  129.     
  130.     
  131.     try:
  132.         names = os.listdir(root)
  133.     except os.error:
  134.         raise StopIteration
  135.  
  136.     if not pattern:
  137.         pass
  138.     pattern = '*'
  139.     pat_list = pattern.split(';')
  140.     for name in names:
  141.         fullname = os.path.normpath(os.path.join(root, name))
  142.         for pat in pat_list:
  143.             if fnmatch.fnmatch(name, pat):
  144.                 if return_folders or not os.path.isdir(fullname):
  145.                     pass
  146.                 None if abs_paths else None<EXCEPTION MATCH>ValueError
  147.                 continue
  148.         
  149.         if recurse and os.path.isdir(fullname):
  150.             for f in walkFiles(fullname, recurse, abs_paths, return_folders, pattern, path):
  151.                 yield f
  152.             
  153.     
  154.  
  155.  
  156. def is_path_writable(path):
  157.     return False
  158.  
  159.  
  160. class TextFormatter:
  161.     LEFT = 0
  162.     CENTER = 1
  163.     RIGHT = 2
  164.     
  165.     def __init__(self, colspeclist):
  166.         self.columns = []
  167.         for colspec in colspeclist:
  168.             self.columns.append(Column(**colspec))
  169.         
  170.  
  171.     
  172.     def compose(self, textlist, add_newline = False):
  173.         numlines = 0
  174.         textlist = list(textlist)
  175.         if len(textlist) != len(self.columns):
  176.             log.error('Formatter: Number of text items does not match columns')
  177.             return None
  178.         for text, column in map(None, textlist, self.columns):
  179.             column.wrap(text)
  180.             numlines = max(numlines, len(column.lines))
  181.         
  182.         complines = [
  183.             ''] * numlines
  184.         for ln in range(numlines):
  185.             for column in self.columns:
  186.                 complines[ln] = complines[ln] + column.getline(ln)
  187.             
  188.         
  189.         if add_newline:
  190.             return '\n'.join(complines) + '\n'
  191.         return '\n'.join(complines)
  192.  
  193.  
  194.  
  195. class Column:
  196.     
  197.     def __init__(self, width = 78, alignment = TextFormatter.LEFT, margin = 0):
  198.         self.width = width
  199.         self.alignment = alignment
  200.         self.margin = margin
  201.         self.lines = []
  202.  
  203.     
  204.     def align(self, line):
  205.         if self.alignment == TextFormatter.CENTER:
  206.             return line.center(self.width)
  207.         if self.alignment == TextFormatter.RIGHT:
  208.             return line.rjust(self.width)
  209.         return line.ljust(self.width)
  210.  
  211.     
  212.     def wrap(self, text):
  213.         self.lines = []
  214.         words = []
  215.         for word in text.split():
  216.             if word <= self.width:
  217.                 words.append(word)
  218.                 continue
  219.             for i in range(0, len(word), self.width):
  220.                 words.append(word[i:i + self.width])
  221.             
  222.         
  223.         if not len(words):
  224.             return None
  225.         current = words.pop(0)
  226.         for word in words:
  227.             increment = 1 + len(word)
  228.             if len(current) + increment > self.width:
  229.                 self.lines.append(self.align(current))
  230.                 current = word
  231.                 continue
  232.             len(words)
  233.             current = current + ' ' + word
  234.         
  235.         self.lines.append(self.align(current))
  236.  
  237.     
  238.     def getline(self, index):
  239.         if index < len(self.lines):
  240.             return ' ' * self.margin + self.lines[index]
  241.         return ' ' * (self.margin + self.width)
  242.  
  243.  
  244.  
  245. class Stack:
  246.     
  247.     def __init__(self):
  248.         self.stack = []
  249.  
  250.     
  251.     def pop(self):
  252.         return self.stack.pop()
  253.  
  254.     
  255.     def push(self, value):
  256.         self.stack.append(value)
  257.  
  258.     
  259.     def as_list(self):
  260.         return self.stack
  261.  
  262.     
  263.     def clear(self):
  264.         self.stack = []
  265.  
  266.     
  267.     def __len__(self):
  268.         return len(self.stack)
  269.  
  270.  
  271.  
  272. class Queue(Stack):
  273.     
  274.     def __init__(self):
  275.         Stack.__init__(self)
  276.  
  277.     
  278.     def get(self):
  279.         return self.stack.pop(0)
  280.  
  281.     
  282.     def put(self, value):
  283.         Stack.push(self, value)
  284.  
  285.  
  286.  
  287. class RingBuffer:
  288.     
  289.     def __init__(self, size_max = 50):
  290.         self.max = size_max
  291.         self.data = []
  292.  
  293.     
  294.     def append(self, x):
  295.         '''append an element at the end of the buffer'''
  296.         self.data.append(x)
  297.         if len(self.data) == self.max:
  298.             self.cur = 0
  299.             self.__class__ = RingBufferFull
  300.         
  301.  
  302.     
  303.     def replace(self, x):
  304.         '''replace the last element instead off appending'''
  305.         self.data[-1] = x
  306.  
  307.     
  308.     def get(self):
  309.         ''' return a list of elements from the oldest to the newest'''
  310.         return self.data
  311.  
  312.  
  313.  
  314. class RingBufferFull:
  315.     
  316.     def __init__(self, n):
  317.         pass
  318.  
  319.     
  320.     def append(self, x):
  321.         self.data[self.cur] = x
  322.         self.cur = (self.cur + 1) % self.max
  323.  
  324.     
  325.     def replace(self, x):
  326.         self.cur = (self.cur - 1) % self.max
  327.         self.data[self.cur] = x
  328.         self.cur = (self.cur + 1) % self.max
  329.  
  330.     
  331.     def get(self):
  332.         return self.data[self.cur:] + self.data[:self.cur]
  333.  
  334.  
  335.  
  336. def sort_dict_by_value(d):
  337.     ''' Returns the keys of dictionary d sorted by their values '''
  338.     items = d.items()
  339.     backitems = [ [
  340.         v[1],
  341.         v[0]] for v in items ]
  342.     backitems.sort()
  343.     return [ backitems[i][1] for i in range(0, len(backitems)) ]
  344.  
  345.  
  346. def commafy(val):
  347.     return unicode(locale.format('%d', val, grouping = True))
  348.  
  349.  
  350. def format_bytes(s, show_bytes = False):
  351.     if s < 1024:
  352.         return ''.join([
  353.             commafy(s),
  354.             ' B'])
  355.     if s < s:
  356.         pass
  357.     elif s < 1048576:
  358.         if show_bytes:
  359.             return ''.join([
  360.                 unicode(round(s / 1024, 1)),
  361.                 u' KB (',
  362.                 commafy(s),
  363.                 ')'])
  364.         return ''.join([
  365.             unicode(round(s / 1024, 1)),
  366.             u' KB'])
  367.     elif s < s:
  368.         pass
  369.     elif s < 1073741824:
  370.         if show_bytes:
  371.             return ''.join([
  372.                 unicode(round(s / 1.04858e+06, 1)),
  373.                 u' MB (',
  374.                 commafy(s),
  375.                 ')'])
  376.         return ''.join([
  377.             unicode(round(s / 1.04858e+06, 1)),
  378.             u' MB'])
  379.     elif show_bytes:
  380.         return ''.join([
  381.             unicode(round(s / 1.07374e+09, 1)),
  382.             u' GB (',
  383.             commafy(s),
  384.             ')'])
  385.     s < 1024
  386.     return ''.join([
  387.         unicode(round(s / 1.07374e+09, 1)),
  388.         u' GB'])
  389.  
  390.  
  391. try:
  392.     make_temp_file = tempfile.mkstemp
  393. except AttributeError:
  394.     
  395.     def make_temp_file(suffix = '', prefix = '', dir = '', text = False):
  396.         path = tempfile.mktemp(suffix)
  397.         fd = os.open(path, os.O_RDWR | os.O_CREAT | os.O_EXCL, 448)
  398.         return (os.fdopen(fd, 'w+b'), path)
  399.  
  400.  
  401.  
  402. def which(command, return_full_path = False):
  403.     path = os.getenv('PATH').split(':')
  404.     path.append('/sbin')
  405.     path.append('/usr/sbin')
  406.     path.append('/usr/local/sbin')
  407.     found_path = ''
  408.     for p in path:
  409.         
  410.         try:
  411.             files = os.listdir(p)
  412.         except OSError:
  413.             continue
  414.             continue
  415.  
  416.         if command in files:
  417.             found_path = p
  418.             break
  419.             continue
  420.     
  421.     if return_full_path:
  422.         if found_path:
  423.             return os.path.join(found_path, command)
  424.         return ''
  425.     return_full_path
  426.     return found_path
  427.  
  428.  
  429. class UserSettings(object):
  430.     
  431.     def __init__(self):
  432.         self.load()
  433.  
  434.     
  435.     def loadDefaults(self):
  436.         self.cmd_print = ''
  437.         path = which('hp-print')
  438.         if len(path) > 0:
  439.             self.cmd_print = 'hp-print -p%PRINTER%'
  440.         else:
  441.             path = which('kprinter')
  442.             if len(path) > 0:
  443.                 self.cmd_print = 'kprinter -P%PRINTER% --system cups'
  444.             else:
  445.                 path = which('gtklp')
  446.                 if len(path) > 0:
  447.                     self.cmd_print = 'gtklp -P%PRINTER%'
  448.                 else:
  449.                     path = which('xpp')
  450.                     if len(path) > 0:
  451.                         self.cmd_print = 'xpp -P%PRINTER%'
  452.                     
  453.         self.cmd_scan = ''
  454.         path = which('xsane')
  455.         if len(path) > 0:
  456.             self.cmd_scan = 'xsane -V %SANE_URI%'
  457.         else:
  458.             path = which('kooka')
  459.             if len(path) > 0:
  460.                 self.cmd_scan = 'kooka'
  461.             else:
  462.                 path = which('xscanimage')
  463.                 if len(path) > 0:
  464.                     self.cmd_scan = 'xscanimage'
  465.                 
  466.         path = which('hp-unload')
  467.         if len(path):
  468.             self.cmd_pcard = 'hp-unload -d %DEVICE_URI%'
  469.         else:
  470.             self.cmd_pcard = 'python %HOME%/unload.py -d %DEVICE_URI%'
  471.         path = which('hp-makecopies')
  472.         if len(path):
  473.             self.cmd_copy = 'hp-makecopies -d %DEVICE_URI%'
  474.         else:
  475.             self.cmd_copy = 'python %HOME%/makecopies.py -d %DEVICE_URI%'
  476.         path = which('hp-sendfax')
  477.         if len(path):
  478.             self.cmd_fax = 'hp-sendfax -d %FAX_URI%'
  479.         else:
  480.             self.cmd_fax = 'python %HOME%/sendfax.py -d %FAX_URI%'
  481.         path = which('hp-fab')
  482.         if len(path):
  483.             self.cmd_fab = 'hp-fab'
  484.         else:
  485.             self.cmd_fab = 'python %HOME%/fab.py'
  486.  
  487.     
  488.     def load(self):
  489.         self.loadDefaults()
  490.         log.debug('Loading user settings...')
  491.         self.auto_refresh = to_bool(user_conf.get('refresh', 'enable', '0'))
  492.         
  493.         try:
  494.             self.auto_refresh_rate = int(user_conf.get('refresh', 'rate', '30'))
  495.         except ValueError:
  496.             self.auto_refresh_rate = 30
  497.  
  498.         
  499.         try:
  500.             self.auto_refresh_type = int(user_conf.get('refresh', 'type', '0'))
  501.         except ValueError:
  502.             self.auto_refresh_type = 0
  503.  
  504.         self.cmd_print = user_conf.get('commands', 'prnt', self.cmd_print)
  505.         self.cmd_scan = user_conf.get('commands', 'scan', self.cmd_scan)
  506.         self.cmd_pcard = user_conf.get('commands', 'pcard', self.cmd_pcard)
  507.         self.cmd_copy = user_conf.get('commands', 'cpy', self.cmd_copy)
  508.         self.cmd_fax = user_conf.get('commands', 'fax', self.cmd_fax)
  509.         self.cmd_fab = user_conf.get('commands', 'fab', self.cmd_fab)
  510.         self.debug()
  511.  
  512.     
  513.     def debug(self):
  514.         log.debug('Print command: %s' % self.cmd_print)
  515.         log.debug('PCard command: %s' % self.cmd_pcard)
  516.         log.debug('Fax command: %s' % self.cmd_fax)
  517.         log.debug('FAB command: %s' % self.cmd_fab)
  518.         log.debug('Copy command: %s ' % self.cmd_copy)
  519.         log.debug('Scan command: %s' % self.cmd_scan)
  520.         log.debug('Auto refresh: %s' % self.auto_refresh)
  521.         log.debug('Auto refresh rate: %s' % self.auto_refresh_rate)
  522.         log.debug('Auto refresh type: %s' % self.auto_refresh_type)
  523.  
  524.     
  525.     def save(self):
  526.         log.debug('Saving user settings...')
  527.         user_conf.set('commands', 'prnt', self.cmd_print)
  528.         user_conf.set('commands', 'pcard', self.cmd_pcard)
  529.         user_conf.set('commands', 'fax', self.cmd_fax)
  530.         user_conf.set('commands', 'scan', self.cmd_scan)
  531.         user_conf.set('commands', 'cpy', self.cmd_copy)
  532.         user_conf.set('refresh', 'enable', self.auto_refresh)
  533.         user_conf.set('refresh', 'rate', self.auto_refresh_rate)
  534.         user_conf.set('refresh', 'type', self.auto_refresh_type)
  535.         self.debug()
  536.  
  537.  
  538.  
  539. def no_qt_message_gtk():
  540.     
  541.     try:
  542.         import gtk
  543.         w = gtk.Window()
  544.         dialog = gtk.MessageDialog(w, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_WARNING, gtk.BUTTONS_OK, 'PyQt not installed. GUI not available. Please check that the PyQt package is installed. Exiting.')
  545.         dialog.run()
  546.         dialog.destroy()
  547.     except ImportError:
  548.         log.error('PyQt not installed. GUI not available. Please check that the PyQt package is installed. Exiting.')
  549.  
  550.  
  551.  
  552. def canEnterGUIMode():
  553.     if not prop.gui_build:
  554.         log.warn('GUI mode disabled in build.')
  555.         return False
  556.     if not os.getenv('DISPLAY'):
  557.         log.warn('No display found.')
  558.         return False
  559.     if not checkPyQtImport():
  560.         log.warn('Qt/PyQt 3 initialization failed.')
  561.         return False
  562.     return True
  563.  
  564.  
  565. def canEnterGUIMode4():
  566.     if not prop.gui_build:
  567.         log.warn('GUI mode disabled in build.')
  568.         return False
  569.     if not os.getenv('DISPLAY'):
  570.         log.warn('No display found.')
  571.         return False
  572.     if not checkPyQtImport4():
  573.         log.warn('Qt/PyQt 4 initialization failed.')
  574.         return False
  575.     return True
  576.  
  577.  
  578. def checkPyQtImport():
  579.     
  580.     try:
  581.         import qt
  582.     except ImportError:
  583.         if os.getenv('DISPLAY') and os.getenv('STARTED_FROM_MENU'):
  584.             no_qt_message_gtk()
  585.         
  586.         log.error('PyQt not installed. GUI not available. Exiting.')
  587.         return False
  588.  
  589.     qtMajor = int(qt.qVersion().split('.')[0])
  590.     if qtMajor < MINIMUM_QT_MAJOR_VER:
  591.         log.error('Incorrect version of Qt installed. Ver. 3.0.0 or greater required.')
  592.         return False
  593.     
  594.     try:
  595.         pyqtVersion = qt.PYQT_VERSION_STR
  596.     except AttributeError:
  597.         qtMajor < MINIMUM_QT_MAJOR_VER
  598.         qtMajor < MINIMUM_QT_MAJOR_VER
  599.         pyqtVersion = qt.PYQT_VERSION
  600.     except:
  601.         qtMajor < MINIMUM_QT_MAJOR_VER
  602.  
  603.     while pyqtVersion.count('.') < 2:
  604.         pyqtVersion += '.0'
  605.         continue
  606.         qtMajor < MINIMUM_QT_MAJOR_VER
  607.     (maj_ver, min_ver, pat_ver) = pyqtVersion.split('.')
  608.     return True
  609.  
  610.  
  611. def checkPyQtImport4():
  612.     
  613.     try:
  614.         import PyQt4
  615.     except ImportError:
  616.         return False
  617.  
  618.     return True
  619.  
  620.  
  621. try:
  622.     from string import Template
  623. except ImportError:
  624.     
  625.     class _multimap:
  626.         '''Helper class for combining multiple mappings.
  627.  
  628.         Used by .{safe_,}substitute() to combine the mapping and keyword
  629.         arguments.
  630.         '''
  631.         
  632.         def __init__(self, primary, secondary):
  633.             self._primary = primary
  634.             self._secondary = secondary
  635.  
  636.         
  637.         def __getitem__(self, key):
  638.             
  639.             try:
  640.                 return self._primary[key]
  641.             except KeyError:
  642.                 return self._secondary[key]
  643.  
  644.  
  645.  
  646.     
  647.     class _TemplateMetaclass(type):
  648.         pattern = '\n        %(delim)s(?:\n          (?P<escaped>%(delim)s) |   # Escape sequence of two delimiters\n          (?P<named>%(id)s)      |   # delimiter and a Python identifier\n          {(?P<braced>%(id)s)}   |   # delimiter and a braced identifier\n          (?P<invalid>)              # Other ill-formed delimiter exprs\n        )\n        '
  649.         
  650.         def __init__(cls, name, bases, dct):
  651.             super(_TemplateMetaclass, cls).__init__(name, bases, dct)
  652.             if 'pattern' in dct:
  653.                 pattern = cls.pattern
  654.             else:
  655.                 pattern = _TemplateMetaclass.pattern % {
  656.                     'delim': re.escape(cls.delimiter),
  657.                     'id': cls.idpattern }
  658.             cls.pattern = re.compile(pattern, re.IGNORECASE | re.VERBOSE)
  659.  
  660.  
  661.     
  662.     class Template:
  663.         '''A string class for supporting $-substitutions.'''
  664.         __metaclass__ = _TemplateMetaclass
  665.         delimiter = '$'
  666.         idpattern = '[_a-z][_a-z0-9]*'
  667.         
  668.         def __init__(self, template):
  669.             self.template = template
  670.  
  671.         
  672.         def _invalid(self, mo):
  673.             i = mo.start('invalid')
  674.             lines = self.template[:i].splitlines(True)
  675.             if not lines:
  676.                 colno = 1
  677.                 lineno = 1
  678.             else:
  679.                 colno = i - len(''.join(lines[:-1]))
  680.                 lineno = len(lines)
  681.             raise ValueError('Invalid placeholder in string: line %d, col %d' % (lineno, colno))
  682.  
  683.         
  684.         def substitute(self, *args, **kws):
  685.             if len(args) > 1:
  686.                 raise TypeError('Too many positional arguments')
  687.             len(args) > 1
  688.             if not args:
  689.                 mapping = kws
  690.             elif kws:
  691.                 mapping = _multimap(kws, args[0])
  692.             else:
  693.                 mapping = args[0]
  694.             
  695.             def convert(mo):
  696.                 if not mo.group('named'):
  697.                     pass
  698.                 named = mo.group('braced')
  699.                 if named is not None:
  700.                     val = mapping[named]
  701.                     return '%s' % val
  702.                 if mo.group('escaped') is not None:
  703.                     return self.delimiter
  704.                 raise ValueError('Unrecognized named group in pattern', self.pattern)
  705.  
  706.             return self.pattern.sub(convert, self.template)
  707.  
  708.         
  709.         def safe_substitute(self, *args, **kws):
  710.             if len(args) > 1:
  711.                 raise TypeError('Too many positional arguments')
  712.             len(args) > 1
  713.             if not args:
  714.                 mapping = kws
  715.             elif kws:
  716.                 mapping = _multimap(kws, args[0])
  717.             else:
  718.                 mapping = args[0]
  719.             
  720.             def convert(mo):
  721.                 named = mo.group('named')
  722.                 if named is not None:
  723.                     
  724.                     try:
  725.                         return '%s' % mapping[named]
  726.                     except KeyError:
  727.                         return self.delimiter + named
  728.                     
  729.  
  730.                 None<EXCEPTION MATCH>KeyError
  731.                 braced = mo.group('braced')
  732.                 if braced is not None:
  733.                     
  734.                     try:
  735.                         return '%s' % mapping[braced]
  736.                     except KeyError:
  737.                         return self.delimiter + '{' + braced + '}'
  738.                     
  739.  
  740.                 None<EXCEPTION MATCH>KeyError
  741.                 if mo.group('escaped') is not None:
  742.                     return self.delimiter
  743.                 if mo.group('invalid') is not None:
  744.                     return self.delimiter
  745.                 raise ValueError('Unrecognized named group in pattern', self.pattern)
  746.  
  747.             return self.pattern.sub(convert, self.template)
  748.  
  749.  
  750.  
  751.  
  752. def cat(s):
  753.     globals = sys._getframe(1).f_globals.copy()
  754.     if 'self' in globals:
  755.         del globals['self']
  756.     
  757.     locals = sys._getframe(1).f_locals.copy()
  758.     if 'self' in locals:
  759.         del locals['self']
  760.     
  761.     return Template(s).substitute(sys._getframe(1).f_globals, **locals)
  762.  
  763. identity = string.maketrans('', '')
  764. unprintable = identity.translate(identity, string.printable)
  765.  
  766. def printable(s):
  767.     return s.translate(identity, unprintable)
  768.  
  769.  
  770. def any(S, f = (lambda x: x)):
  771.     for x in S:
  772.         if f(x):
  773.             return True
  774.     
  775.     return False
  776.  
  777.  
  778. def all(S, f = (lambda x: x)):
  779.     for x in S:
  780.         if not f(x):
  781.             return False
  782.     
  783.     return True
  784.  
  785. BROWSERS = [
  786.     'firefox',
  787.     'mozilla',
  788.     'konqueror',
  789.     'galeon',
  790.     'skipstone']
  791. BROWSER_OPTS = {
  792.     'firefox': '-new-window',
  793.     'mozilla': '',
  794.     'konqueror': '',
  795.     'galeon': '-w',
  796.     'skipstone': '' }
  797.  
  798. def find_browser():
  799.     if platform_avail and platform.system() == 'Darwin':
  800.         return 'open'
  801.     for b in BROWSERS:
  802.         if which(b):
  803.             return b
  804.     else:
  805.         return None
  806.     return which(b)
  807.  
  808.  
  809. def openURL(url, use_browser_opts = True):
  810.     if platform_avail and platform.system() == 'Darwin':
  811.         cmd = 'open "%s"' % url
  812.         log.debug(cmd)
  813.         os.system(cmd)
  814.     else:
  815.         for b in BROWSERS:
  816.             bb = which(b)
  817.             if bb:
  818.                 bb = os.path.join(bb, b)
  819.                 if use_browser_opts:
  820.                     cmd = '%s %s "%s" &' % (bb, BROWSER_OPTS[b], url)
  821.                 else:
  822.                     cmd = '%s "%s" &' % (bb, url)
  823.                 log.debug(cmd)
  824.                 os.system(cmd)
  825.                 break
  826.                 continue
  827.         
  828.  
  829.  
  830. def uniqueList(input):
  831.     temp = []
  832.     _[1]
  833.     return temp
  834.  
  835.  
  836. def list_move_up(l, m, cmp = None):
  837.     for i in range(1, len(l)):
  838.         if f(i):
  839.             l[i - 1] = l[i]
  840.             l[i] = l[i - 1]
  841.             continue
  842.         None if cmp is None else (None, None, None)
  843.     
  844.  
  845.  
  846. def list_move_down(l, m, cmp = None):
  847.     for i in range(len(l) - 2, -1, -1):
  848.         if f(i):
  849.             l[i] = l[i + 1]
  850.             l[i + 1] = l[i]
  851.             continue
  852.         None if cmp is None else (None, None, None)
  853.     
  854.  
  855.  
  856. class XMLToDictParser:
  857.     
  858.     def __init__(self):
  859.         self.stack = []
  860.         self.data = { }
  861.         self.last_start = ''
  862.  
  863.     
  864.     def startElement(self, name, attrs):
  865.         self.stack.append(unicode(name).lower())
  866.         self.last_start = unicode(name).lower()
  867.         if len(attrs):
  868.             for a in attrs:
  869.                 self.stack.append(unicode(a).lower())
  870.                 self.addData(attrs[a])
  871.                 self.stack.pop()
  872.             
  873.         
  874.  
  875.     
  876.     def endElement(self, name):
  877.         if name.lower() == self.last_start:
  878.             self.addData('')
  879.         
  880.         self.stack.pop()
  881.  
  882.     
  883.     def charData(self, data):
  884.         data = unicode(data).strip()
  885.         if data and self.stack:
  886.             self.addData(data)
  887.         
  888.  
  889.     
  890.     def addData(self, data):
  891.         self.last_start = ''
  892.         
  893.         try:
  894.             data = int(data)
  895.         except ValueError:
  896.             data = unicode(data)
  897.  
  898.         stack_str = '-'.join(self.stack)
  899.         stack_str_0 = '-'.join([
  900.             stack_str,
  901.             '0'])
  902.         
  903.         try:
  904.             self.data[stack_str]
  905.         except KeyError:
  906.             
  907.             try:
  908.                 self.data[stack_str_0]
  909.             except KeyError:
  910.                 self.data[stack_str] = data
  911.  
  912.             j = 2
  913.             while True:
  914.                 
  915.                 try:
  916.                     self.data['-'.join([
  917.                         stack_str,
  918.                         unicode(j)])]
  919.                 except KeyError:
  920.                     self.data['-'.join([
  921.                         stack_str,
  922.                         unicode(j)])] = data
  923.                     break
  924.  
  925.                 j += 1
  926.  
  927.         self.data[stack_str_0] = self.data[stack_str]
  928.         self.data['-'.join([
  929.             stack_str,
  930.             '1'])] = data
  931.         del self.data[stack_str]
  932.  
  933.     
  934.     def parseXML(self, text):
  935.         parser = expat.ParserCreate()
  936.         parser.StartElementHandler = self.startElement
  937.         parser.EndElementHandler = self.endElement
  938.         parser.CharacterDataHandler = self.charData
  939.         parser.Parse(text.encode('utf-8'), True)
  940.         return self.data
  941.  
  942.  
  943.  
  944. def dquote(s):
  945.     return ''.join([
  946.         '"',
  947.         s,
  948.         '"'])
  949.  
  950. if sys.hexversion < 33686512:
  951.     
  952.     def xlstrip(s, chars = ' '):
  953.         i = 0
  954.         for c, i in zip(s, range(len(s))):
  955.             if c not in chars:
  956.                 break
  957.                 continue
  958.         
  959.         return s[i:]
  960.  
  961.     
  962.     def xrstrip(s, chars = ' '):
  963.         return xreverse(xlstrip(xreverse(s), chars))
  964.  
  965.     
  966.     def xreverse(s):
  967.         l = list(s)
  968.         l.reverse()
  969.         return ''.join(l)
  970.  
  971.     
  972.     def xstrip(s, chars = ' '):
  973.         return xreverse(xlstrip(xreverse(xlstrip(s, chars)), chars))
  974.  
  975. else:
  976.     xlstrip = string.lstrip
  977.     xrstrip = string.rstrip
  978.     xstrip = string.strip
  979.  
  980. def getBitness():
  981.     if platform_avail:
  982.         return int(platform.architecture()[0][:-3])
  983.     return struct.calcsize('P') << 3
  984.  
  985.  
  986. def getProcessor():
  987.     if platform_avail:
  988.         return platform.machine().replace(' ', '_').lower()
  989.     return 'i686'
  990.  
  991.  
  992. def getEndian():
  993.     if sys.byteorder == 'big':
  994.         return BIG_ENDIAN
  995.     return LITTLE_ENDIAN
  996.  
  997.  
  998. def get_password():
  999.     return getpass.getpass('Enter password: ')
  1000.  
  1001.  
  1002. def run(cmd, log_output = True, password_func = get_password, timeout = 1):
  1003.     output = cStringIO.StringIO()
  1004.     
  1005.     try:
  1006.         child = pexpect.spawn(cmd, timeout = timeout)
  1007.     except pexpect.ExceptionPexpect:
  1008.         return (-1, '')
  1009.  
  1010.     
  1011.     try:
  1012.         while True:
  1013.             update_spinner()
  1014.             i = child.expect([
  1015.                 '[pP]assword:',
  1016.                 pexpect.EOF,
  1017.                 pexpect.TIMEOUT])
  1018.             if child.before:
  1019.                 output.write(child.before)
  1020.                 if log_output:
  1021.                     log.debug(child.before)
  1022.                 
  1023.             
  1024.             if i == 0:
  1025.                 if password_func is not None:
  1026.                     child.sendline(password_func())
  1027.                 else:
  1028.                     child.sendline(get_password())
  1029.             password_func is not None
  1030.             if i == 1:
  1031.                 break
  1032.                 continue
  1033.             if i == 2:
  1034.                 continue
  1035.                 continue
  1036.     except Exception:
  1037.         e = None
  1038.         log.error('Exception: %s' % e)
  1039.  
  1040.     cleanup_spinner()
  1041.     child.close()
  1042.     return (child.exitstatus, output.getvalue())
  1043.  
  1044.  
  1045. def expand_range(ns):
  1046.     '''Credit: Jean Brouwers, comp.lang.python 16-7-2004
  1047.        Convert a string representation of a set of ranges into a
  1048.        list of ints, e.g.
  1049.        u"1-4, 7, 9-12" --> [1,2,3,4,7,9,10,11,12]
  1050.     '''
  1051.     fs = []
  1052.     for n in ns.split(u','):
  1053.         n = n.strip()
  1054.         r = n.split('-')
  1055.         if len(r) == 2:
  1056.             h = r[0].rstrip(u'0123456789')
  1057.             r[0] = r[0][len(h):]
  1058.             if not r[0] and r[1]:
  1059.                 raise ValueError, 'empty range: ' + n
  1060.             r[1]
  1061.             r = [ int(i, 10) for i in r ]
  1062.             if r[0] > r[1]:
  1063.                 raise ValueError, 'bad range: ' + n
  1064.             r[0] > r[1]
  1065.             for i in range(r[0], r[1] + 1):
  1066.                 fs.append(h % i)
  1067.             
  1068.         []
  1069.         fs.append(n)
  1070.     
  1071.     fs = []([ (n, i) for i, n in enumerate(fs) ]).keys()
  1072.     fs = _[4]
  1073.     fs.sort()
  1074.     return fs
  1075.  
  1076.  
  1077. def collapse_range(x):
  1078.     ''' Convert a list of integers into a string
  1079.         range representation:
  1080.         [1,2,3,4,7,9,10,11,12] --> u"1-4,7,9-12"
  1081.     '''
  1082.     if not x:
  1083.         return ''
  1084.     s = [
  1085.         str(x[0])]
  1086.     c = x[0]
  1087.     r = False
  1088.     for i in x[1:]:
  1089.         if i == c + 1:
  1090.             r = True
  1091.         elif r:
  1092.             s.append(u'-%s,%s' % (c, i))
  1093.             r = False
  1094.         else:
  1095.             s.append(u',%s' % i)
  1096.         c = i
  1097.     
  1098.     if r:
  1099.         s.append(u'-%s' % i)
  1100.     
  1101.     return ''.join(s)
  1102.  
  1103.  
  1104. def createSequencedFilename(basename, ext, dir = None, digits = 3):
  1105.     if dir is None:
  1106.         dir = os.getcwd()
  1107.     
  1108.     m = 0
  1109.     for f in walkFiles(dir, recurse = False, abs_paths = False, return_folders = False, pattern = '*', path = None):
  1110.         (r, e) = os.path.splitext(f)
  1111.         if r.startswith(basename) and ext == e:
  1112.             
  1113.             try:
  1114.                 i = int(r[len(basename):])
  1115.             except ValueError:
  1116.                 continue
  1117.  
  1118.             m = max(m, i)
  1119.             continue
  1120.     
  1121.     return os.path.join(dir, '%s%0*d%s' % (basename, digits, m + 1, ext))
  1122.  
  1123.  
  1124. def validate_language(lang, default = 'en_US'):
  1125.     if lang is None:
  1126.         (loc, encoder) = locale.getdefaultlocale()
  1127.     else:
  1128.         lang = lang.lower().strip()
  1129.         for loc, ll in supported_locales.items():
  1130.             if lang in ll:
  1131.                 break
  1132.                 continue
  1133.         else:
  1134.             loc = 'en_US'
  1135.     return loc
  1136.  
  1137.  
  1138. def gen_random_uuid():
  1139.     
  1140.     try:
  1141.         import uuid
  1142.         return str(uuid.uuid4())
  1143.     except ImportError:
  1144.         uuidgen = which('uuidgen')
  1145.         if uuidgen:
  1146.             uuidgen = os.path.join(uuidgen, 'uuidgen')
  1147.             return commands.getoutput(uuidgen)
  1148.         return ''
  1149.     except:
  1150.         uuidgen
  1151.  
  1152.  
  1153.  
  1154. class RestTableFormatter(object):
  1155.     
  1156.     def __init__(self, header = None):
  1157.         self.header = header
  1158.         self.rows = []
  1159.  
  1160.     
  1161.     def add(self, row_data):
  1162.         self.rows.append(row_data)
  1163.  
  1164.     
  1165.     def output(self, w):
  1166.         if self.rows:
  1167.             num_cols = len(self.rows[0])
  1168.             for r in self.rows:
  1169.                 if len(r) != num_cols:
  1170.                     log.error('Invalid number of items in row: %s' % r)
  1171.                     return None
  1172.             
  1173.             if len(self.header) != num_cols:
  1174.                 log.error('Invalid number of items in header.')
  1175.             
  1176.             col_widths = []
  1177.             for x, c in enumerate(self.header):
  1178.                 max_width = len(c)
  1179.                 for r in self.rows:
  1180.                     max_width = max(max_width, len(r[x]))
  1181.                 
  1182.                 col_widths.append(max_width + 2)
  1183.             
  1184.             x = '+'
  1185.             for c in col_widths:
  1186.                 x = ''.join([
  1187.                     x,
  1188.                     '-' * (c + 2),
  1189.                     '+'])
  1190.             
  1191.             x = ''.join([
  1192.                 x,
  1193.                 '\n'])
  1194.             w.write(x)
  1195.             if self.header:
  1196.                 x = '|'
  1197.                 for i, c in enumerate(col_widths):
  1198.                     x = ''.join([
  1199.                         x,
  1200.                         ' ',
  1201.                         self.header[i],
  1202.                         ' ' * (c + 1 - len(self.header[i])),
  1203.                         '|'])
  1204.                 
  1205.                 x = ''.join([
  1206.                     x,
  1207.                     '\n'])
  1208.                 w.write(x)
  1209.                 x = '+'
  1210.                 for c in col_widths:
  1211.                     x = ''.join([
  1212.                         x,
  1213.                         '=' * (c + 2),
  1214.                         '+'])
  1215.                 
  1216.                 x = ''.join([
  1217.                     x,
  1218.                     '\n'])
  1219.                 w.write(x)
  1220.             
  1221.             for j, r in enumerate(self.rows):
  1222.                 x = '|'
  1223.                 for i, c in enumerate(col_widths):
  1224.                     x = ''.join([
  1225.                         x,
  1226.                         ' ',
  1227.                         self.rows[j][i],
  1228.                         ' ' * (c + 1 - len(self.rows[j][i])),
  1229.                         '|'])
  1230.                 
  1231.                 x = ''.join([
  1232.                     x,
  1233.                     '\n'])
  1234.                 w.write(x)
  1235.                 x = '+'
  1236.                 for c in col_widths:
  1237.                     x = ''.join([
  1238.                         x,
  1239.                         '-' * (c + 2),
  1240.                         '+'])
  1241.                 
  1242.                 x = ''.join([
  1243.                     x,
  1244.                     '\n'])
  1245.                 w.write(x)
  1246.             
  1247.         else:
  1248.             log.error('No data rows')
  1249.  
  1250.  
  1251.  
  1252. def mixin(cls):
  1253.     import inspect
  1254.     locals = inspect.stack()[1][0].f_locals
  1255.     if '__module__' not in locals:
  1256.         raise TypeError('Must call mixin() from within class def.')
  1257.     '__module__' not in locals
  1258.     dict = cls.__dict__.copy()
  1259.     dict.pop('__doc__', None)
  1260.     dict.pop('__module__', None)
  1261.     locals.update(dict)
  1262.  
  1263. USAGE_OPTIONS = ('[OPTIONS]', '', 'heading', False)
  1264. USAGE_LOGGING1 = ('Set the logging level:', '-l<level> or --logging=<level>', 'option', False)
  1265. USAGE_LOGGING2 = ('', '<level>: none, info\\*, error, warn, debug (\\*default)', 'option', False)
  1266. USAGE_LOGGING3 = ('Run in debug mode:', '-g (same as option: -ldebug)', 'option', False)
  1267. USAGE_LOGGING_PLAIN = ('Output plain text only:', '-t', 'option', False)
  1268. USAGE_ARGS = ('[PRINTER|DEVICE-URI]', '', 'heading', False)
  1269. USAGE_ARGS2 = ('[PRINTER]', '', 'heading', False)
  1270. USAGE_DEVICE = ('To specify a device-URI:', '-d<device-uri> or --device=<device-uri>', 'option', False)
  1271. USAGE_PRINTER = ('To specify a CUPS printer:', '-p<printer> or --printer=<printer>', 'option', False)
  1272. USAGE_BUS1 = ('Bus to probe (if device not specified):', '-b<bus> or --bus=<bus>', 'option', False)
  1273. USAGE_BUS2 = ('', '<bus>: cups\\*, usb\\*, net, bt, fw, par\\* (\\*defaults) (Note: bt and fw not supported in this release.)', 'option', False)
  1274. USAGE_HELP = ('This help information:', '-h or --help', 'option', True)
  1275. USAGE_SPACE = ('', '', 'space', False)
  1276. USAGE_EXAMPLES = ('Examples:', '', 'heading', False)
  1277. USAGE_NOTES = ('Notes:', '', 'heading', False)
  1278. USAGE_STD_NOTES1 = ('If device or printer is not specified, the local device bus is probed and the program enters interactive mode.', '', 'note', False)
  1279. USAGE_STD_NOTES2 = ('If -p\\* is specified, the default CUPS printer will be used.', '', 'note', False)
  1280. USAGE_SEEALSO = ('See Also:', '', 'heading', False)
  1281. USAGE_LANGUAGE = ('Set the language:', '-q <lang> or --lang=<lang>. Use -q? or --lang=? to see a list of available language codes.', 'option', False)
  1282. USAGE_LANGUAGE2 = ('Set the language:', '--lang=<lang>. Use --lang=? to see a list of available language codes.', 'option', False)
  1283. USAGE_MODE = ('[MODE]', '', 'header', False)
  1284. USAGE_NON_INTERACTIVE_MODE = ('Run in non-interactive mode:', '-n or --non-interactive', 'option', False)
  1285. USAGE_GUI_MODE = ('Run in graphical UI mode:', '-u or --gui (Default)', 'option', False)
  1286. USAGE_INTERACTIVE_MODE = ('Run in interactive mode:', '-i or --interactive', 'option', False)
  1287. if sys_conf.get('configure', 'ui-toolkit', 'qt3') == 'qt3':
  1288.     USAGE_USE_QT3 = ('Use Qt3:', '--qt3 (Default)', 'option', False)
  1289.     USAGE_USE_QT4 = ('Use Qt4:', '--qt4', 'option', False)
  1290. else:
  1291.     USAGE_USE_QT3 = ('Use Qt3:', '--qt3', 'option', False)
  1292.     USAGE_USE_QT4 = ('Use Qt4:', '--qt4 (Default)', 'option', False)
  1293.  
  1294. def ttysize():
  1295.     ln1 = commands.getoutput('stty -a').splitlines()[0]
  1296.     vals = {
  1297.         'rows': None,
  1298.         'columns': None }
  1299.     for ph in ln1.split(';'):
  1300.         x = ph.split()
  1301.         if len(x) == 2:
  1302.             vals[x[0]] = x[1]
  1303.             vals[x[1]] = x[0]
  1304.             continue
  1305.     
  1306.     
  1307.     try:
  1308.         rows = int(vals['rows'])
  1309.         cols = int(vals['columns'])
  1310.     except TypeError:
  1311.         (rows, cols) = (25, 80)
  1312.  
  1313.     return (rows, cols)
  1314.  
  1315.  
  1316. def usage_formatter(override = 0):
  1317.     (rows, cols) = ttysize()
  1318.     if override:
  1319.         col1 = override
  1320.         col2 = cols - col1 - 8
  1321.     else:
  1322.         col1 = int(cols / 3) - 8
  1323.         col2 = cols - col1 - 8
  1324.     return TextFormatter(({
  1325.         'width': col1,
  1326.         'margin': 2 }, {
  1327.         'width': col2,
  1328.         'margin': 2 }))
  1329.  
  1330.  
  1331. def format_text(text_list, typ = 'text', title = '', crumb = '', version = ''):
  1332.     '''
  1333.     Format usage text in multiple formats:
  1334.         text: for --help in the console
  1335.         rest: for conversion with rst2web for the website
  1336.         man: for manpages
  1337.     '''
  1338.     if typ == 'text':
  1339.         formatter = usage_formatter()
  1340.         for line in text_list:
  1341.             (text1, text2, format, trailing_space) = line
  1342.             text1 = text1.replace('\\', '')
  1343.             text2 = text2.replace('\\', '')
  1344.             if format == 'summary':
  1345.                 log.info(log.bold(text1))
  1346.                 log.info('')
  1347.                 continue
  1348.             if format in ('para', 'name', 'seealso'):
  1349.                 log.info(text1)
  1350.                 if trailing_space:
  1351.                     log.info('')
  1352.                 
  1353.             trailing_space
  1354.             if format in ('heading', 'header'):
  1355.                 log.info(log.bold(text1))
  1356.                 continue
  1357.             if format in ('option', 'example'):
  1358.                 log.info(formatter.compose((text1, text2), trailing_space))
  1359.                 continue
  1360.             if format == 'note':
  1361.                 if text1.startswith(' '):
  1362.                     log.info('\t' + text1.lstrip())
  1363.                 else:
  1364.                     log.info(text1)
  1365.             text1.startswith(' ')
  1366.             if format == 'space':
  1367.                 log.info('')
  1368.                 continue
  1369.         
  1370.         log.info('')
  1371.     elif typ == 'rest':
  1372.         (opt_colwidth1, opt_colwidth2) = (0, 0)
  1373.         (exmpl_colwidth1, exmpl_colwidth2) = (0, 0)
  1374.         (note_colwidth1, note_colwidth2) = (0, 0)
  1375.         for line in text_list:
  1376.             (text1, text2, format, trailing_space) = line
  1377.             if format == 'option':
  1378.                 opt_colwidth1 = max(len(text1), opt_colwidth1)
  1379.                 opt_colwidth2 = max(len(text2), opt_colwidth2)
  1380.                 continue
  1381.             if format == 'example':
  1382.                 exmpl_colwidth1 = max(len(text1), exmpl_colwidth1)
  1383.                 exmpl_colwidth2 = max(len(text2), exmpl_colwidth2)
  1384.                 continue
  1385.             if format == 'note':
  1386.                 note_colwidth1 = max(len(text1), note_colwidth1)
  1387.                 note_colwidth2 = max(len(text2), note_colwidth2)
  1388.                 continue
  1389.         
  1390.         opt_colwidth1 += 4
  1391.         opt_colwidth2 += 4
  1392.         exmpl_colwidth1 += 4
  1393.         exmpl_colwidth2 += 4
  1394.         note_colwidth1 += 4
  1395.         note_colwidth2 += 4
  1396.         opt_tablewidth = opt_colwidth1 + opt_colwidth2
  1397.         exmpl_tablewidth = exmpl_colwidth1 + exmpl_colwidth2
  1398.         note_tablewidth = note_colwidth1 + note_colwidth2
  1399.         log.info('restindex\npage-title: %s\ncrumb: %s\nformat: rest\nfile-extension: html\nencoding: utf8\n/restindex\n' % (title, crumb))
  1400.         t = '%s: %s (ver. %s)' % (crumb, title, version)
  1401.         log.info(t)
  1402.         log.info('=' * len(t))
  1403.         log.info('')
  1404.         links = []
  1405.         needs_header = False
  1406.         for line in text_list:
  1407.             (text1, text2, format, trailing_space) = line
  1408.             if format == 'seealso':
  1409.                 links.append(text1)
  1410.                 text1 = '`%s`_' % text1
  1411.             
  1412.             len1 = len(text1)
  1413.             len2 = len(text2)
  1414.             if format == 'summary':
  1415.                 log.info(''.join([
  1416.                     '**',
  1417.                     text1,
  1418.                     '**']))
  1419.                 log.info('')
  1420.                 continue
  1421.             if format in ('para', 'name'):
  1422.                 log.info('')
  1423.                 log.info(text1)
  1424.                 log.info('')
  1425.                 continue
  1426.             if format in ('heading', 'header'):
  1427.                 log.info('')
  1428.                 log.info('**' + text1 + '**')
  1429.                 log.info('')
  1430.                 needs_header = True
  1431.                 continue
  1432.             if format == 'option':
  1433.                 if needs_header:
  1434.                     log.info('.. class:: borderless')
  1435.                     log.info('')
  1436.                     log.info(''.join([
  1437.                         '+',
  1438.                         '-' * opt_colwidth1,
  1439.                         '+',
  1440.                         '-' * opt_colwidth2,
  1441.                         '+']))
  1442.                     needs_header = False
  1443.                 
  1444.                 if text1 and '`_' not in text1:
  1445.                     log.info(''.join([
  1446.                         '| *',
  1447.                         text1,
  1448.                         '*',
  1449.                         ' ' * (opt_colwidth1 - len1 - 3),
  1450.                         '|',
  1451.                         text2,
  1452.                         ' ' * (opt_colwidth2 - len2),
  1453.                         '|']))
  1454.                 elif text1:
  1455.                     log.info(''.join([
  1456.                         '|',
  1457.                         text1,
  1458.                         ' ' * (opt_colwidth1 - len1),
  1459.                         '|',
  1460.                         text2,
  1461.                         ' ' * (opt_colwidth2 - len2),
  1462.                         '|']))
  1463.                 else:
  1464.                     log.info(''.join([
  1465.                         '|',
  1466.                         ' ' * opt_colwidth1,
  1467.                         '|',
  1468.                         text2,
  1469.                         ' ' * (opt_colwidth2 - len2),
  1470.                         '|']))
  1471.                 log.info(''.join([
  1472.                     '+',
  1473.                     '-' * opt_colwidth1,
  1474.                     '+',
  1475.                     '-' * opt_colwidth2,
  1476.                     '+']))
  1477.                 continue
  1478.             if format == 'example':
  1479.                 if needs_header:
  1480.                     log.info('.. class:: borderless')
  1481.                     log.info('')
  1482.                     log.info(''.join([
  1483.                         '+',
  1484.                         '-' * exmpl_colwidth1,
  1485.                         '+',
  1486.                         '-' * exmpl_colwidth2,
  1487.                         '+']))
  1488.                     needs_header = False
  1489.                 
  1490.                 if text1 and '`_' not in text1:
  1491.                     log.info(''.join([
  1492.                         '| *',
  1493.                         text1,
  1494.                         '*',
  1495.                         ' ' * (exmpl_colwidth1 - len1 - 3),
  1496.                         '|',
  1497.                         text2,
  1498.                         ' ' * (exmpl_colwidth2 - len2),
  1499.                         '|']))
  1500.                 elif text1:
  1501.                     log.info(''.join([
  1502.                         '|',
  1503.                         text1,
  1504.                         ' ' * (exmpl_colwidth1 - len1),
  1505.                         '|',
  1506.                         text2,
  1507.                         ' ' * (exmpl_colwidth2 - len2),
  1508.                         '|']))
  1509.                 else:
  1510.                     log.info(''.join([
  1511.                         '|',
  1512.                         ' ' * exmpl_colwidth1,
  1513.                         '|',
  1514.                         text2,
  1515.                         ' ' * (exmpl_colwidth2 - len2),
  1516.                         '|']))
  1517.                 log.info(''.join([
  1518.                     '+',
  1519.                     '-' * exmpl_colwidth1,
  1520.                     '+',
  1521.                     '-' * exmpl_colwidth2,
  1522.                     '+']))
  1523.                 continue
  1524.             if format == 'seealso':
  1525.                 if text1 and '`_' not in text1:
  1526.                     log.info(text1)
  1527.                 
  1528.             '`_' not in text1
  1529.             if format == 'note':
  1530.                 if needs_header:
  1531.                     log.info('.. class:: borderless')
  1532.                     log.info('')
  1533.                     log.info(''.join([
  1534.                         '+',
  1535.                         '-' * note_colwidth1,
  1536.                         '+',
  1537.                         '-' * note_colwidth2,
  1538.                         '+']))
  1539.                     needs_header = False
  1540.                 
  1541.                 if text1.startswith(' '):
  1542.                     log.info(''.join([
  1543.                         '|',
  1544.                         ' ' * (note_tablewidth + 1),
  1545.                         '|']))
  1546.                 
  1547.                 log.info(''.join([
  1548.                     '|',
  1549.                     text1,
  1550.                     ' ' * ((note_tablewidth - len1) + 1),
  1551.                     '|']))
  1552.                 log.info(''.join([
  1553.                     '+',
  1554.                     '-' * note_colwidth1,
  1555.                     '+',
  1556.                     '-' * note_colwidth2,
  1557.                     '+']))
  1558.                 continue
  1559.             if format == 'space':
  1560.                 log.info('')
  1561.                 continue
  1562.         
  1563.         for l in links:
  1564.             log.info('\n.. _`%s`: %s.html\n' % (l, l.replace('hp-', '')))
  1565.         
  1566.         log.info('')
  1567.     elif typ == 'man':
  1568.         log.info('.TH "%s" 1 "%s" Linux "User Manuals"' % (crumb, version))
  1569.         log.info('.SH NAME\n%s \\- %s' % (crumb, title))
  1570.         for line in text_list:
  1571.             (text1, text2, format, trailing_space) = line
  1572.             text1 = text1.replace('\\*', '*')
  1573.             text2 = text2.replace('\\*', '*')
  1574.             len1 = len(text1)
  1575.             len2 = len(text2)
  1576.             if format == 'summary':
  1577.                 log.info('.SH SYNOPSIS')
  1578.                 log.info('.B %s' % text1.replace('Usage:', ''))
  1579.                 continue
  1580.             if format == 'name':
  1581.                 log.info('.SH DESCRIPTION\n%s' % text1)
  1582.                 continue
  1583.             if format in ('option', 'example', 'note'):
  1584.                 if text1:
  1585.                     log.info('.IP "%s"\n%s' % (text1, text2))
  1586.                 else:
  1587.                     log.info(text2)
  1588.             text1
  1589.             if format in ('header', 'heading'):
  1590.                 log.info('.SH %s' % text1.upper().replace(':', '').replace('[', '').replace(']', ''))
  1591.                 continue
  1592.             if format in 'seealso, para':
  1593.                 log.info(text1)
  1594.                 continue
  1595.         
  1596.         log.info('.SH AUTHOR')
  1597.         log.info('HPLIP (Hewlett-Packard Linux Imaging and Printing) is an')
  1598.         log.info('HP developed solution for printing, scanning, and faxing with')
  1599.         log.info('HP inkjet and laser based printers in Linux.')
  1600.         log.info('.SH REPORTING BUGS')
  1601.         log.info('The HPLIP Launchpad.net site')
  1602.         log.info('.B https://launchpad.net/hplip')
  1603.         log.info('is available to get help, report')
  1604.         log.info('bugs, make suggestions, discuss the HPLIP project or otherwise')
  1605.         log.info('contact the HPLIP Team.')
  1606.         log.info('.SH COPYRIGHT')
  1607.         log.info('Copyright (c) 2001-9 Hewlett-Packard Development Company, L.P.')
  1608.         log.info('.LP')
  1609.         log.info('This software comes with ABSOLUTELY NO WARRANTY.')
  1610.         log.info('This is free software, and you are welcome to distribute it')
  1611.         log.info('under certain conditions. See COPYING file for more details.')
  1612.         log.info('')
  1613.     
  1614.  
  1615.  
  1616. def log_title(program_name, version, show_ver = True):
  1617.     log.info('')
  1618.     if show_ver:
  1619.         log.info(log.bold('HP Linux Imaging and Printing System (ver. %s)' % prop.version))
  1620.     else:
  1621.         log.info(log.bold('HP Linux Imaging and Printing System'))
  1622.     log.info(log.bold('%s ver. %s' % (program_name, version)))
  1623.     log.info('')
  1624.     log.info('Copyright (c) 2001-9 Hewlett-Packard Development Company, LP')
  1625.     log.info('This software comes with ABSOLUTELY NO WARRANTY.')
  1626.     log.info('This is free software, and you are welcome to distribute it')
  1627.     log.info('under certain conditions. See COPYING file for more details.')
  1628.     log.info('')
  1629.  
  1630.  
  1631. def ireplace(old, search, replace):
  1632.     regex = '(?i)' + re.escape(search)
  1633.     return re.sub(regex, replace, old)
  1634.  
  1635.  
  1636. def su_sudo():
  1637.     su_sudo_str = None
  1638.     if which('kdesu'):
  1639.         su_sudo_str = 'kdesu -- %s'
  1640.     elif utils.which('/usr/lib/kde4/libexec/kdesu'):
  1641.         su_sudo_str = '/usr/lib/kde4/libexec/kdesu -- %s'
  1642.     elif utils.which('kdesudo'):
  1643.         su_sudo_str = 'kdesudo -- %s'
  1644.     elif which('gnomesu'):
  1645.         su_sudo_str = 'gnomesu -c "%s"'
  1646.     elif which('gksu'):
  1647.         su_sudo_str = 'gksu "%s"'
  1648.     
  1649.     return su_sudo_str
  1650.  
  1651.  
  1652. def unescape(text):
  1653.     
  1654.     def fixup(m):
  1655.         text = m.group(0)
  1656.         if text[:2] == '&#':
  1657.             
  1658.             try:
  1659.                 if text[:3] == '&#x':
  1660.                     return chr(int(text[3:-1], 16))
  1661.                 return chr(int(text[2:-1]))
  1662.             except ValueError:
  1663.                 pass
  1664.             except:
  1665.                 None<EXCEPTION MATCH>ValueError
  1666.             
  1667.  
  1668.         None<EXCEPTION MATCH>ValueError
  1669.         
  1670.         try:
  1671.             text = chr(htmlentitydefs.name2codepoint[text[1:-1]])
  1672.         except KeyError:
  1673.             pass
  1674.  
  1675.         return text
  1676.  
  1677.     return re.sub('&#?\\w+;', fixup, text)
  1678.  
  1679.  
  1680. def escape(s):
  1681.     if not isinstance(s, unicode):
  1682.         s = unicode(s)
  1683.     
  1684.     s = s.replace(u'&', u'&')
  1685.     for c in htmlentitydefs.codepoint2name:
  1686.         if c != 38:
  1687.             s = s.replace(unichr(c), u'&%s;' % htmlentitydefs.codepoint2name[c])
  1688.             continue
  1689.     
  1690.     for c in range(32) + range(127, 160):
  1691.         s = s.replace(unichr(c), u'&#%d;' % c)
  1692.     
  1693.     return s
  1694.  
  1695.